package com.asiainfo.rt.execution;

import java.io.BufferedReader;
import java.io.File;
import java.io.FileReader;
import java.io.IOException;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.net.URL;
import java.net.URLClassLoader;
import java.util.ArrayList;

public class CommandLineWrapper {

	public static void main(String[] args) throws ClassNotFoundException,
			NoSuchMethodException, InvocationTargetException,
			IllegalAccessException, IOException, InstantiationException {
		ArrayList urls = new ArrayList();
		File file = new File(args[0]);
		BufferedReader reader = new BufferedReader(new FileReader(file));
		try {
			while (reader.ready()) {
				String fileName = reader.readLine();
				try {
					urls.add(new File(fileName).toURI().toURL());
				} catch (NoSuchMethodError e) {
					urls.add(new File(fileName).toURL());
				}
			}
		} finally {
			reader.close();
		}
		file.delete();
		String progClass = args[1];
		String[] progArgs = new String[args.length - 2];
		System.arraycopy(args, 2, progArgs, 0, progArgs.length);
		Object loader = new URLClassLoader(
				(URL[]) (URL[]) urls.toArray(new URL[urls.size()]), null);
		String classloader = System.getProperty("java.system.class.loader");
		if (classloader != null) {
			try {
				loader = (ClassLoader) Class.forName(classloader)
						.getConstructor(new Class[] { ClassLoader.class })
						.newInstance(new Object[] { loader });
			} catch (Exception e) {
			}
		}
		Class mainClass = ((ClassLoader) loader).loadClass(progClass);
		Thread.currentThread().setContextClassLoader((ClassLoader) loader);
		Class mainArgType = new String[0].getClass();
		Method main = mainClass.getMethod("main", new Class[] { mainArgType });
		ensureAccess(main);
		main.invoke(null, new Object[] { progArgs });
	}

	private static void ensureAccess(Object reflectionObject) {
		Class aClass = reflectionObject.getClass();
		try {
			Method setAccessibleMethod = aClass.getMethod("setAccessible",
					new Class[] { Boolean.TYPE });
			setAccessibleMethod.invoke(reflectionObject,
					new Object[] { Boolean.TRUE });
		} catch (Exception e) {
		}
	}

	private CommandLineWrapper() {
	}
}